﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SanctusSoftware.Logging;
using System.IO;
using SanctusSoftware.Logging.WSUpload;
using ICSharpCode.SharpZipLib.Zip;

namespace SanctusSoftware.Logging.WinForms
{
    public partial class ErrorTransmissionForm : Form
    {
        public ErrorTransmissionForm(byte[] errorInformation, byte[] screenCapture)
        {
            InitializeComponent();

            ErrorInformationBytes = errorInformation;
            ScreenCaptureBytes = screenCapture;
        }

        private void ErrorTransmissionForm_Load(object sender, EventArgs e)
        {
            sendButton.Focus();
        }

        #region Public Properties (UI)

        private string softwareProductName = string.Empty;

        public string SoftwareProductName 
        {
            get
            {
                return softwareProductName;
            }
            set
            {
                softwareProductName = value;
                initialMessageFormattedTextEditor.Value = initialMessageFormattedTextEditor.Value.ToString().Replace("{SoftwareProductName}", softwareProductName);
                // TODO: Change link text box
            }
        }

        #endregion

        #region Public Properties (Data)

        public byte[] ErrorInformationBytes { get; private set; }

        public string ErrorInformation
        {
            get
            {
                ASCIIEncoding encoding = new ASCIIEncoding();
                return encoding.GetString(ErrorInformationBytes);
            }
        }

        public byte[] ScreenCaptureBytes { get; private set; }

        private Image screenCapture = null;

        public Image ScreenCapture
        {
            get
            {
                if (screenCapture == null)
                {
                    MemoryStream ms = new MemoryStream(this.ScreenCaptureBytes);
                    screenCapture = Image.FromStream(ms);
                    ms.Close();
                }
                return screenCapture;
            }
        }

        #endregion

        #region Building Zip File

        private byte[] GetZipBytes()
        {

            MemoryStream ms = new MemoryStream();

            DirectoryInfo tempDirectory = new DirectoryInfo(Path.GetTempPath());
            DirectoryInfo logDirectory = tempDirectory.CreateSubdirectory("SSET");

            if (errorInformationCheckEditor.Checked)
            {
                File.WriteAllBytes(Path.Combine(logDirectory.FullName, "errorlog.txt"), ErrorInformationBytes);    
            }
            if (screenShotCheckEditor.Checked)
            {
                File.WriteAllBytes(Path.Combine(logDirectory.FullName, "screenshot.png"), ScreenCaptureBytes);    
            }

            FastZip fz = new FastZip();
            fz.CreateZip(ms, logDirectory.FullName, false, null, null);

            // Clean Up the Temp Directory
            logDirectory.Delete(true);

            return ms.ToArray();

        }

        #endregion

        #region Send

        // TODO: Use background worker?

        private void sendButton_Click(object sender, EventArgs e)
        {
            Upload();    
        }

        bool uploading = false;

        private void Upload()
        {
            try
            {
                uploading = true;
                uploadFailedPanel.Visible = false;
                tryAgainButton.Visible = false;
                ultraProgressBar1.Value = 0;
                uploadStatusLabel.Text = string.Empty;
                displayTabControl.Tabs["Status"].Selected = true;
                buttonsTabControl.Tabs[1].Selected = true;
                Application.DoEvents();

                WSUploader uploader = new WSUploader("Log.zip", GetZipBytes());
                uploader.UploadingChunk += new EventHandler<UploadingChunkEventArgs>(uploader_UploadingChunk);
                uploader.ChunkUploaded += new EventHandler<UploadChunkEventArgs>(uploader_ChunkUploaded);
                uploader.UploadStatusChanged += new EventHandler<UploadStatusEventArgs>(uploader_UploadStatusChanged);
                uploader.UploadCanceled += new EventHandler(uploader_UploadCanceled);
                uploader.UploadCompleted += new EventHandler(uploader_UploadCompleted);
                uploader.UploadFailed += new EventHandler(uploader_UploadFailed);
                uploader.Upload();
                uploading = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                uploading = false;
                uploadFailedPanel.Visible = true;
            }
        }


        void uploader_UploadFailed(object sender, EventArgs e)
        {
            tryAgainButton.Visible = true;
            uploadFailedPanel.Visible = true;
        }



        void uploader_UploadingChunk(object sender, UploadingChunkEventArgs e)
        {
            if (cancel == true)
            {
                e.Cancel = true;
                cancel = false;
            }
        }

        void uploader_UploadStatusChanged(object sender, UploadStatusEventArgs e)
        {
            uploadStatusLabel.Text = e.Status;
            ultraProgressBar1.Value = e.Percent;
            Application.DoEvents();
        }

        void uploader_ChunkUploaded(object sender, UploadChunkEventArgs e)
        {
        }

        void uploader_UploadCanceled(object sender, EventArgs e)
        {
            UploadCanceled();
        }

        private void UploadCanceled()
        {
            // Go back to previous state
            displayTabControl.Tabs[0].Selected = true;
            buttonsTabControl.Tabs[0].Selected = true;
        }

        void uploader_UploadCompleted(object sender, EventArgs e)
        {
            ThankYou();
        }

        bool cancel = false;

        private void cancelButton_Click(object sender, EventArgs e)
        {
            if (uploading)
            {
                cancel = true;    
            }
            else
            {
                UploadCanceled();
            }
        }

        private void tryAgainButton_Click(object sender, EventArgs e)
        {
            Upload();    
        }

        #endregion

        #region Save

        private void saveButton_Click(object sender, EventArgs e)
        {

            try
            {

                SaveFileDialog sfd = new SaveFileDialog();
                sfd.CreatePrompt = false;
                sfd.Filter = "ZIP File (*.zip)|*.zip";
                sfd.OverwritePrompt = true;
                sfd.ValidateNames = true;

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    File.WriteAllBytes(sfd.FileName, GetZipBytes());
                    ThankYou();
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }

        }

        #endregion

        #region Thank-You

        private void ThankYou()
        {
            
            

            displayTabControl.Tabs[2].Selected = true;
            buttonsTabControl.Tabs[2].Selected = true;
            Application.DoEvents();
            closeTimer.Enabled = true;

        }

        private void closeTimer_Tick(object sender, EventArgs e)
        {
            this.Close();
        }

        #endregion



        private void dontSendButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void whatAmISendingLabel_Click(object sender, EventArgs e)
        {

            try
            {
                new ErrorTransmissionDetailsForm(this.ErrorInformation, ScreenCapture).ShowDialog();
            }
            catch (Exception ex)
            {
                
            }

        }

        private void closeButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }



        private void buttonsTabControl_SelectedTabChanged(object sender, Infragistics.Win.UltraWinTabControl.SelectedTabChangedEventArgs e)
        {
            foreach (Control c in e.Tab.TabPage.Controls)
            {
                c.Enabled = true;
            }

            if (e.PreviousSelectedTab != null)
            {
                foreach (Control c in e.Tab.TabPage.Controls)
                {
                    c.Enabled = true;
                }
            }
        }




    }
}
